package tv.acgn.advertisement.index.service;

import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tv.acgn.advertisement.index.config.IndexFileConfig;
import tv.acgn.advertisement.index.dao.AdPlanDao;
import tv.acgn.advertisement.index.dao.AdUnitDao;
import tv.acgn.advertisement.index.dao.AdUnitDistrictDao;
import tv.acgn.advertisement.index.dao.AdUnitInterestDao;
import tv.acgn.advertisement.index.dao.AdUnitKeywordDao;
import tv.acgn.advertisement.index.dao.CreativeDao;
import tv.acgn.advertisement.index.dao.CreativeUnitDao;
import tv.acgn.advertisement.index.datatable.AdPlanTableItem;
import tv.acgn.advertisement.index.datatable.AdUnitDistrictTableItem;
import tv.acgn.advertisement.index.datatable.AdUnitInterestTableItem;
import tv.acgn.advertisement.index.datatable.AdUnitKeywordTableItem;
import tv.acgn.advertisement.index.datatable.AdUnitTableItem;
import tv.acgn.advertisement.index.datatable.CreativeTableItem;
import tv.acgn.advertisement.index.datatable.CreativeUnitTableItem;
import tv.acgn.advertisement.index.enumconst.AuditStatus;
import tv.acgn.advertisement.index.po.AdPlanPO;
import tv.acgn.advertisement.index.po.AdUnitPO;
import tv.acgn.advertisement.index.po.CreativePO;
import tv.acgn.advertisement.index.po.CreativeUnitPO;
import tv.acgn.advertisement.index.po.unit_condition.AdUnitDistrict;
import tv.acgn.advertisement.index.po.unit_condition.AdUnitInterest;
import tv.acgn.advertisement.index.po.unit_condition.AdUnitKeyword;
import tv.acgn.advertisement.index.utils.UserUtils;
import tv.acgn.advertisement.servicebase.enumconst.CommonStatus;
import tv.acgn.advertisement.servicebase.utils.JsonUtils;

/**
 * @author : junG
 * @program : advertisement-ad-index-config
 * @description : 数据库索引导出服务
 * @date : 2019-09-08 17:05
 **/

@Service
@Slf4j
public class DataIndexExportService {

    @Autowired
    private IndexFileConfig indexFileConfig;
    @Autowired
    private AdPlanDao adPlanDao;
    @Autowired
    private AdUnitDao adUnitDao;
    @Autowired
    private CreativeDao creativeDao;
    @Autowired
    private CreativeUnitDao creativeUnitDao;
    @Autowired
    private AdUnitInterestDao adUnitInterestDao;
    @Autowired
    private AdUnitDistrictDao adUnitDistrictDao;
    @Autowired
    private AdUnitKeywordDao adUnitKeywordDao;

    /**
     * 导出推广计划AdPlan数据表
     *
     * @param fileName 导出后的文件名 默认 ad_plan.data
     */
    public void exportAdPlanTable(String fileName) {
        log.warn("时间{}，{}导出了推广计划表 ", LocalDateTime.now(), UserUtils.getOperator());
        List<AdPlanPO> adPlanPOList = adPlanDao.findAllByPlanStatus(CommonStatus.VALID.getStatus())
            .orElseGet(Collections::emptyList);

        List<AdPlanTableItem> adPlanTableItemList = adPlanPOList.parallelStream().map(x -> {
            return AdPlanTableItem.builder()
                .planId(x.getPlanId())
                .planName(x.getPlanName())
                .userId(x.getUserId())
                .planStatus(x.getPlanStatus())
                .startDate(x.getStartDate())
                .endDate(x.getEndDate()).build();
        }).collect(Collectors.toList());

        if (StringUtils.isBlank(fileName)) {
            fileName = indexFileConfig.getAD_PLAN();
        }
        this.fileExportToDisk(fileName, adPlanTableItemList);
    }

    /**
     * 导出推广单元AdUnit数据表
     *
     * @param fileName 导出后的文件名 默认 ad_unit.data
     */
    public void exportAdUnitTable(String fileName) {
        log.warn("时间{}，{}导出了推广单元表 ", LocalDateTime.now(), UserUtils.getOperator());

        List<AdUnitPO> adUnitPoList = adUnitDao.findAllByUnitStatus(CommonStatus.VALID.getStatus())
            .orElseGet(Collections::emptyList);

        List<AdUnitTableItem> adUnitTableItemList = adUnitPoList.parallelStream().map(x -> {
            return AdUnitTableItem.builder()
                .unitId(x.getUnitId())
                .planId(x.getPlanId())
                .unitName(x.getUnitName())
                .unitStatus(x.getUnitStatus())
                .budget(x.getBudget()).build();
        }).collect(Collectors.toList());

        if (StringUtils.isBlank(fileName)) {
            fileName = indexFileConfig.getAD_UNIT();
        }
        this.fileExportToDisk(fileName, adUnitTableItemList);
    }

    /**
     * 导出创意Creative数据表
     *
     * @param fileName 导出后的文件名 默认 ad_creative.data
     */
    public void exportCreativeTable(String fileName) {
        log.warn("时间{}，{}导出了创意表 ", LocalDateTime.now(), UserUtils.getOperator());

        List<CreativePO> creativePoList = creativeDao.findAllByAuditStatus(AuditStatus.PASS.getType())
            .orElseGet(Collections::emptyList);

        List<CreativeTableItem> adUnitTableItemList = creativePoList.parallelStream().map(x -> {
            return CreativeTableItem.builder()
                .creativeId(x.getCreativeId())
                .name(x.getName())
                .type(x.getType())
                .materialType(x.getMaterialType())
                .height(x.getHeight())
                .width(x.getWidth())
                .size(x.getSize())
                .duration(x.getDuration())
                .URI(x.getURI()).build();
        }).collect(Collectors.toList());

        if (StringUtils.isBlank(fileName)) {
            fileName = indexFileConfig.getAD_CREATIVE();
        }
        this.fileExportToDisk(fileName, creativePoList);
    }

    /**
     * 导出创意Creative与推广单元关系数据表
     *
     * @param fileName 导出后的文件名 默认 ad_creative_relation_unit.data
     */
    public void exportCreativeUnitTable(String fileName) {
        log.warn("时间{}，{}导出了创意与推广单元表 ", LocalDateTime.now(), UserUtils.getOperator());

        List<CreativeUnitPO> creativeUnitPoList = Optional.of(creativeUnitDao.findAll())
            .orElseGet(Collections::emptyList);

        List<CreativeUnitTableItem> creativeUnitTableItemList = creativeUnitPoList.parallelStream().map(x -> {
            return CreativeUnitTableItem.builder()
                .creativeUnitId(x.getCreativeUnitId())
                .creativeId(x.getCreativeId())
                .unitId(x.getUnitId()).build();
        }).collect(Collectors.toList());

        if (StringUtils.isBlank(fileName)) {
            fileName = indexFileConfig.getAD_CREATIVE_RELATION_UNIT();
        }
        this.fileExportToDisk(fileName, creativeUnitTableItemList);
    }

    /**
     * 导出推广单元AdUnit与兴趣Interest关系数据表
     *
     * @param fileName 导出后的文件名 默认 ad_unit_interest.data
     */
    public void exportAdUnitInterestTable(String fileName) {
        log.warn("时间{}，{}导出了推广单元与兴趣表 ", LocalDateTime.now(), UserUtils.getOperator());

        List<AdUnitInterest> adUnitInterestList = Optional.of(adUnitInterestDao.findAll())
            .orElseGet(Collections::emptyList);

        List<AdUnitInterestTableItem> adUnitInterestTableItemList = adUnitInterestList.parallelStream().map(x -> {
            return AdUnitInterestTableItem.builder()
                .unitInterestId(x.getUnitInterestId())
                .unitId(x.getUnitId())
                .interestTag(x.getInterestTag())
                .build();
        }).collect(Collectors.toList());

        if (StringUtils.isBlank(fileName)) {
            fileName = indexFileConfig.getAD_UNIT_INTEREST();
        }
        this.fileExportToDisk(fileName, adUnitInterestTableItemList);
    }

    /**
     * 导出推广单元AdUnit与地域district关系数据表
     *
     * @param fileName 导出后的文件名 默认 ad_unit_district.data
     */
    public void exportAdUnitDistrictTable(String fileName) {
        log.warn("时间{}，{}导出了推广单元与地区表 ", LocalDateTime.now(), UserUtils.getOperator());

        List<AdUnitDistrict> adUnitDistrictList = Optional.of(adUnitDistrictDao.findAll())
            .orElseGet(Collections::emptyList);

        List<AdUnitDistrictTableItem> adUnitDistrictTableItemList = adUnitDistrictList.parallelStream().map(x -> {
            return AdUnitDistrictTableItem.builder()
                .districtId(x.getDistrictId())
                .province(x.getProvince())
                .state(x.getState())
                .city(x.getCity())
                .county(x.getCounty())
                .build();
        }).collect(Collectors.toList());

        if (StringUtils.isBlank(fileName)) {
            fileName = indexFileConfig.getAD_UNIT_DISTRICT();
        }
        this.fileExportToDisk(fileName, adUnitDistrictTableItemList);
    }

    /**
     * 导出推广单元AdUnit与关键字keyword关系数据表
     *
     * @param fileName 导出后的文件名 默认 ad_unit_keyword.data
     */
    public void exportAdUnitKeywordTable(String fileName) {
        log.warn("时间{}，{}导出了推广单元与关键词表 ", LocalDateTime.now(), UserUtils.getOperator());

        List<AdUnitKeyword> adUnitKeywordList = Optional.of(adUnitKeywordDao.findAll())
            .orElseGet(Collections::emptyList);

        List<AdUnitKeywordTableItem> adUnitKeywordTableItemList = adUnitKeywordList.parallelStream().map(x -> {
            return AdUnitKeywordTableItem.builder()
                .unitKeywordId(x.getUnitKeywordId())
                .unitId(x.getUnitId())
                .keyword(x.getKeyword())
                .build();
        }).collect(Collectors.toList());

        if (StringUtils.isBlank(fileName)) {
            fileName = indexFileConfig.getAD_UNIT_KEYWORD();
        }
        this.fileExportToDisk(fileName, adUnitKeywordTableItemList);
    }

    /**
     * 文件导出并存储到磁盘
     */
    public void fileExportToDisk(String fileName, List exportTables) {
        String pathStr = indexFileConfig.getDATA_ROOT_DIR() + fileName;
        Path path = Paths.get(pathStr);
        try (BufferedWriter writer = Files.newBufferedWriter(path)) {
            for (Object item : exportTables) {
                writer.write(JsonUtils.toJsonString(item));
                writer.newLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
            log.error("导出文件错误 文件名{}", fileName);
        }
    }
}
